
#pragma once

#ifdef __cplusplus
        #define EXTERN_C extern "C" {
#else
        #define EXTERN_C extern 
#endif


#ifdef __cplusplus
        #define EXTERN_C_END }
#else
        #define EXTERN_C_END  
#endif


void CleanStructExpr(struct StExpr* expr);

/**
*\fn struct StExpr * CreateBinaryExpr(enum EnType type, struct StExpr *left_expr, struct StExpr *right_expr)
*\brief Функция для создания бинарного выражения.
*\param [in] type Тип нового выражения.
*\param [in] left_expr Левая часть выражения.
*\param [in] right_expr Правая часть выражения.
*\return <struct StExpr*> Новое выражение.
*/
struct StExpr * CreateBinaryExpr(enum EnType type, struct StExpr *left_expr, struct StExpr *right_expr);

/**
*\fn struct StExpr* CreateExprSet(struct StSet *expr)
*\brief Функция для создания нового выражения множества.
*\param [in] expr Элементы множества.
*\return <struct StExpr> Новое выражение множества.
*/
struct StExpr* CreateExprSet(struct StSet *expr);

/**
*\fn struct StProgram * CreateProgram(char * Id, struct StVarDecList* vars, struct StFuncStmtList* funcs)
*\brief Функция для создания корня дерева.
*\param [in] Id Имя программы.
*\param [in] vars Глобальные переменные.
*\param [in] funcs Список функций программы.
*\return <struct StProgram*> Корень дерева с программой.
*/
struct StProgram * CreateProgram(char * Id, struct StVarDecList* vars, struct StFuncStmtList* funcs);

/**
*\fn struct StExpr * CreateUnaryExpr(enum EnType type, struct StExpr *left_expr)
*\brief Функция для создания унарного выражения.
*\param [in] type Тип выражения.
*\param [in] left_expr Левая часть выражения.
*\return <struct StExpr*> Новое выражение.
*/
struct StExpr * CreateUnaryExpr(enum EnType type, struct StExpr *left_expr);

/**
*\fn struct StExpr * CreateFunctionCallExpr(char* Id, struct StExprList* list)
*\brief Функция для создания выражения вызова функции.
*\param [in] Id Имя функции.
*\param [in] list
*/
struct StExpr * CreateFunctionCallExpr(char* Id, struct StExprList* list);

struct StExpr * CreateIdentifierExpr(char* Id);

struct StExpr * CreateConstIntExpr(int constInt);

struct StExpr * CreateConstRealExpr(float constReal);

struct StExpr * CreateCharacterExpr(char* character);

struct StExpr * CreateStringExpr(char* string);

struct StExprList * CreateExpressionList(struct StExpr* expr);

struct StExprList * AddToExpressionList(struct StExprList* list, struct StExpr* expr);

struct StSet * CreateSetExpr(int first, int last, char* first1, char* last1);

struct StSet * CreateSetExpr1(struct StSetList* list);

struct StSetList * CreateSetListExpr(int num);

struct StSetList * CreateSetListExpr1(char* id);

struct StSetList * AddToSetList(struct StSetList* list, int num);

struct StSetList * AddToSetList1(struct StSetList* list, char* id);

struct StVarDec * CreateVariableDeclaration(struct StSetList* list, struct StTypeSpec* type, struct StArrayList* array_list);

struct StArrayList * CreateArrayList(struct StSetList* list);

struct StArrayList * AddToArrayList(struct StArrayList* listArray, struct StSetList* list);

struct StSetList * CreateConstIntList(int num);

struct StSetList * AddToConstIntList(struct StSetList *list, int num);

struct StSetList * CreateIdList(char* name);

struct StSetList * AddToIdList(struct StSetList *list, char* name);

struct StVarDecList * CreateVarDeclarationList(struct StVarDec* varDec);

struct StVarDecList * AddToVarDeclarationList(struct StVarDecList* list, struct StVarDec* varDec);

struct StTypeSpec * CreateType(enum EnTypeSpec type, struct StArrayList* array);

struct StStmt * CreateExprStatement(struct StExpr *expr);

struct StStmtList * CreateStatementList(struct StStmt * stmt);

struct StStmtList * AddToStatementList(struct StStmtList * list, struct StStmt * stmt);

struct StStmt * CreateCaseStmt(enum EnTypeStmt type, char* Id, struct StOptionList *optionList, struct StStmtList * list);

struct StOptionList * CreateOptionList(struct StLabelListOptions * labels, struct StStmtList * list);

struct StOptionList * AddToOptionList(struct StOptionList * optionList, struct StLabelListOptions *labels, struct StStmtList * list);

struct StLabelListOptions * CreateLabelListOptions(char * str1, char* str2);

struct StLabelListOptions * AddToLabelListOptions(struct StLabelListOptions *list, char * str1, char* str2);

struct StStmt * CreateIfStmt(enum EnTypeStmt type, struct StIfStmtCondition * condition, struct StStmtList * stmtList);

struct StIfStmtCondition * CreateIfStmtCondition(struct StExpr * expr, struct StStmtList * stmtList);

struct StIfStmtCondition * AddToIfStmtCondition(struct StIfStmtCondition *list, struct StExpr * expr, struct StStmtList * stmtList);

struct StStmt * CreateCycle(enum EnTypeStmt type, struct StExpr* expr1, struct StExpr* expr2, struct StStmtList* list, char* var, int num);

struct StStmt * CreateJumpStmt(enum EnTypeStmt type, struct StExpr* expr);

struct StFuncDef * CreateFunction(char* Id, struct StVarDecList* parametrList, struct StTypeSpec* type, struct StVarDecList *varList, struct StStmtList* stmtList);

struct StFuncStmtList * CreateFunctionList(struct StFuncDef *func);

struct StFuncStmtList * AddToFunctionList(struct StFuncStmtList *list, struct StFuncDef *func);